////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Filename:    IncanGoddessGuts.h                                           //
//  Developer:   Tommy Riddle                                                 //
//  Create date: 10/09/2006                                                   //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Description: This is the class declaration for the slot gut of the        //
//               Australian Slot machine called Incan Goddess.                //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//        Copyright (c) 2006 - Realtime Gaming.  All rights reserved.         //
////////////////////////////////////////////////////////////////////////////////

#if !defined(__IncanGoddessGUTS_H__)
#define __IncanGoddessGUTS_H__

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


#include "slotguts.h"

class IncanGoddessGuts : public SlotGuts
{
public:
	IncanGoddessGuts();

	virtual ~IncanGoddessGuts();

private:
	// Shared enums between client and server
	#include "IncanGoddessCommon.h"

	// Probability Tables
    enum ProbabilityTables
    {
		PROB_TABLE_DOUBLE_OR_SOMETHING_RESULT
	};

	// Helpful lookup arrays.
	static SpinResult m_aLineWinSpinResults[][6];

	static SpinResult m_aScatterWinSpinResults[6];

	static int8 m_aPayLineOffsets[20][5];

	enum ScatterMasks
	{
		SCATTER_REEL_0_MASK = 0x0421,	// 0000 0100 0010 0001
		SCATTER_REEL_1_MASK = 0x0842,	// 0000 1000 0100 0010
		SCATTER_REEL_2_MASK = 0x1084,	// 0001 0000 1000 0100
		SCATTER_REEL_3_MASK = 0x2108,	// 0010 0001 0000 1000
		SCATTER_REEL_4_MASK = 0x4210	// 0100 0010 0001 0000
	};

	// Inline functions to use with the arrays that also do
	// bounds checking.
	static SpinResult lookupLineWinSpinResult( uint8 nIconType, uint8 nCount )
	{
		if ( nIconType < NUM_VALID_ICONS && nCount < 6 )
		{
			return m_aLineWinSpinResults[ nIconType ][ nCount ];
		}

		ASSERT( false );
		return EVT_INVALID;
	}

	static SpinResult lookupScatterWinSpinResult( uint8 nCount )
	{
		if ( nCount < 6 )
		{
			return m_aScatterWinSpinResults[ nCount ];
		}

		ASSERT( false );
		return EVT_INVALID;
	}

	static int32 getPaylineScatterPosition( uint8 Payline )
	{
		int32 nPosition = 0;

		for ( int n = 0; n < 5; n++ )
		{
			int32 nShift = m_aPayLineOffsets[ Payline ][ n ] - 1;

			nShift *= -5;
				
			nPosition |= ( 1 << ( nShift + n ) );
		}

		return nPosition;
	}

	// Helper functions for classifyStops.
	SpinResult getGoddessLineWinResult( uint8* stops, int32& nNumIcons ) const;

	SpinResult getLineWinResultWithPossibleSubstitution(
		uint8* stops, uint8 line, uint8 testIcon, int32& nNumIcons, bool& bSubstitution );

	bool doesGoddessLineWinPayMore( SpinResult srGoddess, SpinResult srOther,
		bool bSubstitution ) const;

	// Helper functions for classifyScatters.
	void tryForJackpot( SlotSpin* spin );

	SpinResult getScatterWinResult( SlotSpin* spin, int32& nNumScatterIcons, int32& nScatterPositions ) const;
	
	void evaluateScatterWin( SlotSpin* spin, SpinResult srScatterResult, int32 nScatterPositions );

	void evaluateFeatureTrigger( SlotSpin* spin, int32 nNumScatterIcons, int32 nScatterPositions );

	enum DoubleOrSomethingFeatureTrigger
	{
		dosftNone,
		dosftNearMiss,
		dosftFeatureTriggered
	};

	DoubleOrSomethingFeatureTrigger getPaylineFeatureTrigger( uint8 nPayline );
	void setPaylineFeatureTrigger( uint8 nPayline, DoubleOrSomethingFeatureTrigger ePaylineResult );

	DoubleOrSomethingFeatureTrigger getScatterFeatureTrigger();
	void setScatterFeatureTrigger( DoubleOrSomethingFeatureTrigger eScatterResult );

	int32 getNumDoubleOrSomethingRounds();
	void initializeNumDoubleOrSomethingRounds();
	void incrementNumDoubleOrSomethingRounds();

	int32 getCurrentDoubleOrSomethingRound();
	void initializeCurrentDoubleOrSomethingRound();
	void incrementCurrentDoubleOrSomethingRound();

	bool getCurrentDoubleOrSomethingResult();
	void setCurrentDoubleOrSomethingResult( bool bResult );

	int32 getCurrentDoubleOrSomethingBetAmount();
	int32 findNextDoubleOrSomethingBetAmount();
	void initializeNextDoubleOrSomethingBetAmount();

public:
	virtual void classifyStops( SpinLine* spinline, uint8* stops, uint8 bet, uint8 line,
		uint8& rtnresult, uint8& multiplier );

	virtual void classifyScatters( SlotSpin *spin );

    virtual bool8 isValidGuts();

    virtual void getGameModeMultiplierAndNoteId( uint8& nGameModeMultiplier, uint8& nNoteId );

	virtual bool8 processClientData( uint8 bonusGameType, int32 bonusDataCount, int32 *bonusData );

protected:
	// Override these framework functions.
	virtual bool8 hasSavedGames();

	void preSpinClassifyResults( SlotSpin* spin );

	void postSpinClassifyResults( SlotSpin* spin );
};


#endif // !defined(__IncanGoddessGUTS_H__)
